// 数组  可以容纳任何类型的值

// ”稀疏“数组
var a = [];
a[0] = 1;
a[2] = 3;
// 没有设置a[1]的值，返回undefined 但是不等同于显式的将 a[1]赋值为 undefined
console.log(a[1]); //undefined
console.log(a.length); // 3

// 数组也是对象，也可以包含字符串键值和属性，但不计入数组长度
// 但是不建议这样做

// 类数组  一组通过数字索引的值
function foo() {
  var arr = Array.prototype.slice.call(arguments); // ES6已废止
  console.log(arr);
}
foo("boo", "bar");

// 字符串  和数组都是类数组
var a = "foo";
var b = ["f", "o", "o"];
// 支持indexOf concat
// 但是
a[1] = "0"; // 错误
console.log(a.charAt(1));
b[1] = "0";
console.log(a, b);
// 字符串不变是 字符串的成员函数不会改变其原始值，而是创建一个新的字符串，数组的成员函数都是在其原始值上操作
// 字符串 反转 先将字符串变为数组，然后反转，然后拼接字符串
var c = a.split("").reverse().join("");
console.log(c);

// 数字 JS没有真正意义上的整数 js使用的是”双精度“格式(即64位二进制) 用的是IEEE754标准
var a = 0.42; // .42
var b = 42.0; // 42.
// 以上的0都可以省略，但是不建议省略
// 特别大 特别小的数字默认用指数格式显示
// 可以用Number对象封装，因此数字可以调用 Number.prototype中的方法
// toFixed() 指定小数部分的显示位数
// toPrecision() 指定有效数位的显示位数
var a = 42.58;
console.log(a.toPrecision(2));
console.log(a.toPrecision(3));
console.log(a.toPrecision(6));

// 42.toFixed(3) 无效语法 .被视为42.中的一部分 没有.属性调用toFixed了
(42).toFixed(3); // 不过这种不多见
(42).toFixed(3); // 这个可以

// 整数检测
Number.isInteger(42); // ES6
// 或者
var num = 42;
typeof num == "number" && num % 1 == 0;

// void运算符 void并不改变表达式的结果，只是让表达式不返回值
var a = 3;
console.log(void a, a);

// 不是数字的数字 --- NaN  not a number 和自身不相等
console.log(NaN != NaN);
// 检查值是否为NaN 不能直接和NaN比较，而应该用 isNaN(a)
// isNaN 检查参数是否不是NaN，也不是数字  这个也不是很准确
var a = 2 / "foo";
var b = "foo";
console.log(isNaN(a));
console.log(isNaN(b));
// 这个方法 检查是不是NaN  ES6
console.log(Number.isNaN(a));
console.log(Number.isNaN(b));

// 无穷数 Infinity
console.log(Infinity / Infinity); // NaN
// 零值 -0 0 数字的符号位用来代表一些信息 比如方向 所以需要-0

// 特殊等式 ES6中 Object.is(..) 来判断两个值是否绝对相等
// 能使用 == 和 ===(参见第 4 章)时就尽量不要使用 Object.is(..)，因为前者效率更高、
// 更为通用。Object.is(..) 主要用来处理那些特殊的相等比较。
var a = 2 / "foo";
var b = -3 * 0;
Object.is(a, NaN);
console.log(Object.is(b, -0));
console.log(Object.is(b, 0));

// 值和引用
// null undefined 字符串 数字 boolean symbol等 简单值 通过值复制的方式来赋值
// 对象(数组，封装对象) 函数 通过引用复制的方式来赋值/传递
function foo(x) {
  x = x + 1;
  console.log(x);
}
var a = 2;
foo(a);
console.log(a);
// x = x + 1 中的x 从引用变成了数字对象  a仍然指向原来的数字对象
